#include "Player.hh"
#include <iostream>
#include "Skill.hh"

namespace DungeonRPG {

Player::Player(const std::string& name, unsigned hp, unsigned atk, unsigned def)
    : Character(name, "A determined adventurer.", hp, atk, def), gold(100) {
    // Initial skills and equipped slots
    addSkill(new HealWounds());
    addSkill(new HeavyStrike());
    equipSkill(0, 0);
    equipSkill(1, 1);
}

unsigned Player::getGold() const {
    return gold;
}

void Player::addGold(unsigned amount) {
    gold += amount;
}

bool Player::spendGold(unsigned amount) {
    // Deduct gold if enough
    if (gold >= amount) {
        gold -= amount;
        return true;
    }
    return false;
}

void Player::display() const {
    // Show base stats + gold
    Character::display();
    std::cout << "Gold: " << gold << "\n";
}

void Player::interact() {
    std::cout << "You are " << name << ". Explore the dungeon!\n";
}

void Player::equipFromInventory(const std::string& name) {
    // Find item by name, equip if valid
    for (size_t i = 0; i < inventory.size(); ++i) {
        if (inventory[i]->name == name) {
            if (inventory[i]->type != ItemType::Equipment) {
                std::cout << "This item cannot be equipped.\n";
                return;
            }
            equipAccessory(inventory[i]);
            inventory.erase(inventory.begin() + i);
            std::cout << name << " equipped.\n";
            return;
        }
    }
    std::cout << "Item not found or not equippable.\n";
}

const std::vector<Item*>& Player::getInventory() const {
    return inventory;
}

bool Player::useItem(const std::string& itemName) {
    // Use item by name
    if (inventory.empty()) {
        std::cout << "Your inventory is empty.\n";
        return false;
    }

    for (auto it = inventory.begin(); it != inventory.end(); ++it) {
        if ((*it)->name == itemName) {
            std::cout << "Using item: " << (*it)->name << "\n";
            bool used = (*it)->use(this);
            if (used) {
                delete *it;
                inventory.erase(it);
            }
            return used;
        }
    }

    std::cout << "Item \"" << itemName << "\" not found in inventory.\n";
    return false;
}

bool Player::hasSkill(const std::string& name) const {
    // Check if skill is already learned
    for (auto* skill : allSkills) {
        if (skill->name == name) return true;
    }
    return false;
}

void Player::learnSkill(Skill* skill) {
    // Learn a skill if not already known
    if (hasSkill(skill->name)) {
        std::cout << "You already know " << skill->name << ".\n";
        return;
    }

    std::cout << "You learned a new skill: " << skill->name << "!\n";
    addSkill(skill);

    // Auto-equip to first available slot
    for (int i = 0; i < 4; ++i) {
        if (!getSkill(i)) {
            equipSkill(allSkills.size() - 1, i);
            break;
        }
    }
}

void Player::tryLearnSkill() {
    // Learn a new skill every 3 victories
    ++victoryCount;
    if (victoryCount % 3 != 0) return;

    std::vector<Skill*> pool;
    if (victoryCount <= 6) {
        pool = { new ShieldBash(), new IceSpike(), new BuffArmor() };
    } else if (victoryCount <= 9) {
        pool = { new Fireball(), new PoisonDart(), new BleedStrike() };
    } else {
        pool = { new DarkPact(), new Fortify(), new LightningStrike() };
    }

    Skill* learned = pool[rand() % pool.size()];
    learnSkill(learned);
}

}
